home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / Libraries / Sherlock 2.0 / DevLibSrc / Main_DevLib / LIBofile.h < prev    next >
Text File  |  1995-02-08  |  10KB  |  314 lines

  1. /*
  2.     devlib:    Header describing the format of the object file.
  3.             Warning: changes to this file affect both the AS and the LINK applications.
  4.     
  5.     source:  LIBofile.h
  6.     started: May 9, 1994.
  7.     version:
  8.         February 3, 1995.
  9.             Added comment nodes.
  10.             Added f_area_comments field to areas.
  11.             Removed f_ref_next field.
  12.             Added LAST_REF bit and related macros.
  13.         May 21, 1994.
  14.             Added abbreviations for byte nodes.
  15.         May 19, 1994.
  16.             Added f_unit_name.
  17.         May 13, 1994.
  18.             Added f_area_index.
  19.         May 12, 1994.
  20.             Added f_area_name.
  21.             Added fh_areas.
  22.         May 11, 1994.
  23.             Area nodes now contain reference lists.
  24.         May 9, 1994.
  25.             All flags are shared between in-memory and file versions.
  26. */
  27.  
  28. #ifndef LIBofile_h_
  29. #define LIBofile_h_
  30.  
  31. #pragma once
  32.  
  33. /*
  34.     Define abbreviations.
  35. */
  36.  
  37. #define f_comment_ptr(p)((f_comment *) (p))
  38. #define f_header_ptr(p)    ((f_header *) (p))
  39. #define f_ref_ptr(p)    ((f_ref_node *) (p))
  40. #define f_tail_ptr(p)    ((f_trailer *) (p))
  41.  
  42. /*
  43.     Define the typedefs of the object file.
  44.     
  45.     An offset is the number of bytes from the start of an object file.
  46.     Offsets are converted to pointers by the fscan routines.
  47.     A zero offset represents a NULL pointer.
  48.     
  49.     An index is a position relative to some (understood) data structure.
  50.     Zero is *not* a valid index and represents an end-of-list.
  51. */
  52.  
  53. typedef ulong                        f_offset;
  54. typedef ulong                        f_index;
  55. typedef struct f_area_node_struct    f_area_node;
  56. typedef struct f_comment_struct     f_comment;
  57. typedef struct f_dict_node_struct    f_dict_node;
  58. typedef struct f_header_struct        f_header;
  59. typedef struct f_ref_node_struct    f_ref_node;
  60. typedef struct f_trailer_struct        f_trailer;
  61. typedef struct f_unit_node_struct    f_unit_node;
  62.  
  63. /*
  64.     An area consists of an ordered sequence of bits, specified by a byte list.
  65.     2/3/95: added  f_area_comments field.
  66. */
  67.  
  68. static struct f_area_node_struct {
  69.     f_index        f_area_index;        /* The file index. */
  70.     ulong        f_area_app_length;    /* Size of the area in the application. */
  71.     ulong        f_area_file_length;    /* Unpadded size of the area in the object file. */
  72.     f_offset    f_area_refs;        /* The references from within this area. */
  73.     f_offset    f_area_bytes;        /* The "byte list" of the area. */
  74.     f_offset    f_area_comments;    /* The comment list. */
  75.     f_index        f_area_name;        /* The dictionary index of the area's name. */
  76. };
  77.  
  78. /*
  79.     The byte list represents the bytes of an area.
  80.     
  81.     I'm unsure about whether to use a byte list,
  82.     so the byte list is used only if USE_BYTE_LIST is #defined.
  83.     The byte list handles larege DCB instructions more efficiently
  84.     and also allows the linker more flexibility in alignment.
  85.  
  86.     fill nodes  are generated from DCB instructions.
  87.     align nodes are generated from ALIGN instructions.
  88.     byte nodes  are generated from all other cnodes.
  89.     byte nodes are followed by the indicated number of bytes.
  90. */
  91.     
  92. #undef  USE_BYTE_LIST
  93. #define USE_BYTE_LIST
  94.  
  95. #ifdef USE_BYTE_LIST
  96.  
  97.     /* Abbreviations. */
  98.     #define f_align_ptr(p)    ((f_align_node *) (p))
  99.     #define f_byte_ptr(p)    ((f_byte_node *) (p))
  100.     #define f_fill_ptr(p)    ((f_fill_node *) (p))
  101.  
  102.     /* Define the type codes in byte nodes. */
  103.     enum { F_BAD_TYPE, F_ALIGN_TYPE, F_BYTE_TYPE, F_FILL_TYPE };
  104.  
  105.     typedef struct f_align_node_struct    f_align_node;
  106.     typedef struct f_byte_node_struct    f_byte_node;
  107.     typedef struct f_fill_node_struct    f_fill_node;
  108.  
  109.     #define BYTE_NODE_HEAD\
  110.         short        f_byte_type;\
  111.         f_offset    f_byte_next
  112.         
  113.     static struct f_align_node_struct {
  114.         BYTE_NODE_HEAD;
  115.         short    f_align_pad;
  116.     };
  117.     
  118.     static struct f_byte_node_struct {
  119.         BYTE_NODE_HEAD;
  120.         ulong    f_byte_size;
  121.     };
  122.     
  123.     static struct f_fill_node_struct {
  124.         BYTE_NODE_HEAD;
  125.         ulong    f_fill_count;
  126.         long    f_fill_val;
  127.     };
  128. #endif
  129.  
  130. /*
  131.     The comment list contains all line and stack comments for an area.
  132.     The list is terminated with a node with a zero comment_kind.
  133. */
  134. static struct f_comment_struct {
  135.     short    f_comment_kind;        /* C_xxx_COMMENT: see below. */
  136.     ulong    f_comment_offset;    /* Stack offset (location counter for line comments) */
  137.     ulong    f_comment_size;        /* Size of variable (not used for line comments) */
  138. };
  139.  
  140. /* Define the possible values of f_comment_kind and comment_kind fields (AScnodes.h). */
  141. enum {
  142.     C_BAD_COMMENT = 0,
  143.     C_AUTO_COMMENT,
  144.     C_BIG_TEMP_COMMENT,
  145.     C_FORMAL_COMMENT,
  146.     C_FTEMP_COMMENT,
  147.     C_HIDDEN_PTR_COMMENT,
  148.     C_LINE_COMMENT,
  149.     C_BAD_LAST_COMMENT
  150. };
  151.  
  152. /*
  153.     The symbol dictionary contains one entry for each symbol defined or
  154.     referenced in the object file.
  155.     Each f_dict node is followed by the padded name of the symbol.
  156. */
  157.  
  158. static struct f_dict_node_struct {
  159.     
  160.     f_index        f_dict_area;    /* The area in which the label is defined, or 0. */
  161.     f_offset    f_dict_offset;    /* Offset of the symbol from the start of the unit. */
  162.     short        f_dict_length;    /* The length of the *unpadded* symbol */
  163.     
  164.         /* Dictionary flags are the same whether on disk or in memory. */
  165.  
  166.     short    dict_flags;        /* Various flags defined below. */
  167. };
  168.     
  169.     /* Define operations on the dict_flag fields. */
  170.  
  171.     enum {
  172.         DEF_DFLAG        = 0x01,    /* 1: the label is defined in this file. */
  173.         GLOBAL_DFLAG    = 0x02,    /* 1: the label is known outside this file. */
  174.         IMPORT_DFLAG    = 0x04,    /* 1: the label is imported from another file. */
  175.         REF_DFLAG        = 0x08    /* 1: the label is referenced in this file. */
  176.     };
  177.     
  178. #define dict_is_defined(i)        ((((i) -> dict_flags) & DEF_DFLAG)    != 0)
  179. #define dict_is_global(i)        ((((i) -> dict_flags) & GLOBAL_DFLAG)    != 0)
  180. #define dict_is_imported(i)        ((((i) -> dict_flags) & IMPORT_DFLAG)    != 0)
  181. #define dict_is_referenced(i)    ((((i) -> dict_flags) & REF_DFLAG)    != 0)
  182.  
  183. #define dict_set_defined(i)        {(i) -> dict_flags |= DEF_DFLAG;}
  184. #define dict_set_global(i)        {(i) -> dict_flags |= GLOBAL_DFLAG;}
  185. #define dict_set_import(i)        {(i) -> dict_flags |= IMPORT_DFLAG;}
  186. #define dict_set_referenced(i)    {(i) -> dict_flags |= REF_DFLAG;}
  187.  
  188. /*
  189.     Object files start with a header.
  190.  
  191.     The version and revision fields must exist in all object files.
  192.     The item field allows object files to have zero items.
  193.     The value of magic must match value in the end field in the trailer.
  194.  
  195.     Headers, f_items and trailers are padded to a LINKER_PADDING boundary
  196.     using the padding macro defined below.
  197. */
  198.  
  199. #define LINK_VERSION    1            /* Development versions are less than 100. */
  200. #define LINK_REVISION    2
  201. #define MAX_REVISION    100
  202. #define LINK_MAGIC        0x1234
  203.  
  204. #define LINKER_PADDING 2
  205. #define padding(size) (size + ((LINKER_PADDING - (size % LINKER_PADDING)) % LINKER_PADDING))
  206.  
  207. static struct f_header_struct {            /* Disk format... */
  208.  
  209.     unsigned short    fh_version;        /* Version of the object file format. */
  210.     unsigned short    fh_revision;    /* Sub-version of the object file format. */
  211.     ulong            fh_magic;        /* Consistency check. */
  212.     ulong            fh_reserved1;    /* Reserved for future use. */
  213.     ulong            fh_reserved2;    /* Reserved for future use. */
  214.     ulong            fh_symbols;        /* The number of symbols in the symbol dictionary. */
  215.     ulong            fh_units;        /* The number of units in the file. */
  216.     ulong            fh_areas;        /* The number of areas in the file. */
  217.     f_offset        fh_dictionary;    /* Offset of the symbol dictionary or 0 if none. */
  218.     f_offset         fh_unit;        /* Offset of the first unit or 0 if none. */
  219. };
  220.  
  221. /*
  222.     Each area contains a list of references contained within the area.
  223.     This list is used by the linker in two ways:
  224.     1) To determine what areas (hense what units) to link into the application.
  225.     2) To patch fields within included areas.
  226.     
  227.     Associating ref nodes with areas instead of units allows
  228.     the linker to allocate code and data areas independently.
  229.  
  230.     Reference nodes represent a reference to an atom of the indicated size.
  231.     
  232.     WARNING:
  233.         We could get rid of the f_ref_next field by using a flag bit.
  234.         That would *not* be a good idea.
  235.         Although the f_ref_next wastes space in the .o file,
  236.         it *saves* main memory in the liner because the linker converts
  237.         f_ref_nodes to in-memory nodes in place!
  238. */
  239.  
  240. static struct f_ref_node_struct {
  241.  
  242.     f_offset    f_ref_next;        /* Next node on the reference list. */
  243.     f_index        f_ref_dict;        /* Index of the label being referenced. */
  244.     ulong        f_ref_offset;    /* Bytes from start of area of the field to be patched. */
  245.     short        f_ref_size;        /* The size of the field to be patched, in bytes. */
  246.     
  247.         /* Reference flags are the same whether on disk or in memory. */
  248.  
  249.     short    ref_flags;    /* Attribute bits: see below */
  250. };
  251.  
  252.     /* Define bits in the ref_flags field. */
  253.  
  254. #define NEG_RFLAG    0x01
  255. #define ref_set_neg(i)    {(i) -> ref_flags |= NEG_RFLAG;}
  256. #define ref_is_neg(i)    ((((i) -> ref_flags) & NEG_RFLAG) != 0)
  257.  
  258. #if 0 /* Use a NULL f_ref_next field, not flag bits, to end the reference list! */
  259.     #define LAST_RFLAG    0x02
  260.     #define ref_set_last(i)    {(i) -> ref_flags |= LAST_RFLAG;}
  261.     #define ref_is_last(i)    ((((i) -> ref_flags) & LAST_RFLAG) != 0)
  262. #endif
  263.  
  264. /*
  265.     The trailer field follows the last file item node.
  266.     This field exists solely as a consistency check on the file.
  267.  
  268.     The assembler pads the file as necessary so that the trailer
  269.     starts on a LINKER_PADDING byte boundary.
  270. */
  271.  
  272. static struct f_trailer_struct {
  273.     ulong    t_file_size;    /* The file size, including the trailer. */
  274.     ulong    t_end;            /* Value of t_end must match value in h_magic. */
  275. };
  276.  
  277. /*
  278.     A unit is the smallest element that can be included or excluded from an
  279.     application by the linker.
  280. */
  281.  
  282. static struct f_unit_node_struct {
  283.  
  284.     f_offset    f_unit_next;        /* Offset of the next unit */
  285.     f_offset    f_unit_code_area;    /* Offset of the unit's code area. */
  286.     f_offset    f_unit_data_area;    /* Offset of the unit's data area. */
  287.     f_index        f_unit_name;        /* The dictionary index of the unit's name. */
  288.     
  289.         /* Unit flags are the same whether on disk or in memory. */
  290.         
  291.     short unit_flags;        /* Various flags defined below. */
  292. };
  293.  
  294. /*
  295.     Define abbreviations for operations on the m_unit_flag fields.
  296.     
  297.     The SCAN_UFLAG field is used only by the linker.
  298. */
  299.     enum {
  300.         PROC_UFLAG        = 0x01,    /* TRUE: the unit is a PROC unit. */
  301.         RECORD_UFLAG    = 0x02,    /* TRUE: the unit is a RECORD unit. */
  302.         SCAN_UFLAG        = 0x04    /* TRUE: the unit is on the scan list. */
  303.     };
  304.  
  305. #define unit_is_on_scan_list(i)    ((((i) -> unit_flags) & SCAN_UFLAG)     != 0)
  306. #define unit_is_proc(i)            ((((i) -> unit_flags) & PROC_UFLAG)        != 0)
  307. #define unit_is_record(i)        ((((i) -> unit_flags) & RECORD_UFLAG)    != 0)
  308.  
  309. #define unit_set_on_scan_list(i)    { (i) -> unit_flags |= SCAN_UFLAG;  }
  310. #define unit_set_proc(i)            { (i) -> unit_flags |= PROC_UFLAG;  }
  311. #define unit_set_record(i)            { (i) -> unit_flags |= RECORD_UFLAG;}
  312.  
  313. #endif /* LIBofile_h_ */
  314.